#pragma once
#include "Matrix.h"
#include "LeastSquare.h"
#include "Polynomial.h"

namespace LatoolNet {

	using namespace System;

  ///
	///<summary>
	/// This class computes a nearest polynomial to fit given arrays 
	/// of x and y by least squares.
	///</summary>
	///
	public ref class PolynomialFitting {
	private:
		PolynomialFitting() {};
	public:
		static Polynomial^ Fit(array<double>^ x, array<double>^ y, int dimension) {
			
			int n = x->Length;
			Matrix^ a = gcnew Matrix(x->Length, dimension + 1);
			Matrix^ b = gcnew Matrix(x->Length, 1);

			double m_ave = 0.0;
			for (int i = 0; i < x->Length; i++) {
				m_ave += x[i];
			}
			m_ave /= x->Length;

			for (int i = 0; i < x->Length; i++) {
				for (int j = 0; j < dimension + 1; j++) {
					a[i, j] = Math::Pow((x[i] - m_ave), j);
				}
				b[i, 0] = y[i];
			}

			LeastSquare::Solve(a, b);
			
			array<double>^ m_b = gcnew array<double>(dimension + 1);
			for (int i = 0; i< dimension + 1; i++) {
				m_b[i] = b[i, 0];
			}

			delete a;
			delete b;

			return gcnew Polynomial(m_b, m_ave);
		};

	};
}